package com.gis3c.sys.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.gis3c.sys.entry.po.Role;
import com.gis3c.sys.entry.vo.RoleModel;
import org.apache.commons.collections.map.HashedMap;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.gis3c.sys.dao.RoleDao;
import com.gis3c.sys.service.RoleService;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class RoleServiceImpl implements RoleService {
	@Autowired private Mapper baseMapper;
	@Resource private RoleDao roleDao;
	
	@Override
	@Transactional(propagation= Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
	public void CreateRole(RoleModel roleModel) {
		Role newRole = baseMapper.map(roleModel,Role.class);
		newRole.setRoleId(UUID.randomUUID().toString());
		newRole.setCreatedTime(new Date());
		roleDao.CreateRole(newRole);
	}

	@Override
	public void DeleteRole(String roleId) {
		roleDao.DeleteRole(roleId);
	}
	
	
	@Override
	public void DeleteRoles(String[] roleIds){
		roleDao.DeleteRoles(roleIds);
	}
	
	@Override
	public void UpdateRole(RoleModel newRole){
		roleDao.UpdateRole(baseMapper.map(newRole,Role.class));
	}
	
	@Override
	public RoleModel FindRoleById(String roleId){
		return baseMapper.map(roleDao.FindRoleById(roleId),RoleModel.class);
	}
	
	@Override
	public List<RoleModel> FindRoleByName(String roleName){
 		return conver2RoleMode(roleDao.FindRoleByName(roleName));
	}
	
	@Override
	public List<RoleModel> FindRoleByAliasName(String aliasName){
		return conver2RoleMode(roleDao.FindRoleByAliasName(aliasName));
	}

	@Override
	public Set<String> findRolesByUserId(String usernId) {
		Set<String> roleIdSet = new HashSet<>();
		roleDao.findRolesByUserId(usernId).forEach(role -> {
			roleIdSet.add(role.getRoleId());
		});
		return roleIdSet;
	}

	@Override
	public Map<String,Object> findRolesByCorrelatedUser(String usernId,Integer pageSize, Integer currentPage){
		Map<String,Object> result = new HashMap<>();
		List<Map<String,Object>> resultData = new ArrayList<>();
		List<Role> roleList = roleDao.RoleList(null,null);
		List<Role> roleListByUserId = roleDao.findRolesByUserId(usernId);

		result.put("count",roleList.size());

		roleList.forEach(role -> {
			RoleModel roleModel = baseMapper.map(role,RoleModel.class);
            Map<String,Object> roleDate = new HashMap<>();
            roleDate.put("roleName",role.getRoleName());
            roleDate.put("roleId",role.getRoleId());
			if(roleListByUserId.contains(role)){
                roleDate.put("LAY_CHECKED",true);
			}
			resultData.add(roleDate);
		});

		if(pageSize != null && currentPage != null){
			result.put("data",resultData.stream()
					.skip(pageSize * (currentPage-1)).limit(pageSize)
					.collect(Collectors.toList())
			);
		}else {
			result.put("data",resultData);
		}

		result.put("code",0);
		result.put("msg","");

		return result;
	}
	@Override
	public Set<String> findRolesByUserName(String userName) {
		Set<String> roleIdSet = new HashSet<>();
		roleDao.findRolesByUserName(userName).forEach(role -> {
			roleIdSet.add(role.getRoleId());
		});
		return roleIdSet;
	}

	@Override
	public List<RoleModel> RoleList(Integer pageSize,Integer currentPage) {
		return conver2RoleMode(roleDao.RoleList(pageSize,currentPage));
	}

	@Override
	public Integer RoleCount() {
		return roleDao.RoleCount();
	}

    @Override
	@Transactional(propagation= Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
    public void correlationRoles(String userId, String... roleIds) {
        roleDao.correlationRoles(userId, roleIds);
    }

    @Override
	@Transactional(propagation= Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
    public void uncorrelationRoles(String userId,String... roleIds){
        roleDao.uncorrelationRoles(userId, roleIds);
    }

	@Override
	@Transactional(propagation= Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
	public Integer correlationMenus(String roleId, String appId, String... menuIds){
		Integer insertNum = 0;
		roleDao.uncorrelationMenus(roleId,appId);
		if(menuIds.length > 0){
			insertNum = roleDao.correlationMenus(roleId, appId,menuIds);
		}
		return insertNum;
	}
	
	@Override
	@Transactional(propagation= Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
	public Integer uncorrelationMenus(String roleId) {
		return roleDao.uncorrelationMenus(roleId);
	}


	private List<RoleModel> conver2RoleMode(List<Role> queryList){
		List<RoleModel> resultList = new ArrayList<>();
		queryList.forEach(queryRole->resultList.add(baseMapper.map(queryRole,RoleModel.class)));
		return resultList;
	}

	private List<Role> conver2Role(List<RoleModel> queryList){
		List<Role> resultList = new ArrayList<>();
		queryList.forEach(queryRole->resultList.add(baseMapper.map(queryRole,Role.class)));
		return resultList;
	}
}
